package org.example.rzfx.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 * 
 * 用于异步处理日志回写任务，避免阻塞主线程
 */
@Configuration
@EnableAsync
@Slf4j
public class ThreadPoolConfig {
    
    /**
     * 日志回写专用线程池
     * 
     * 配置说明：
     * - 核心线程数：4（保持活跃，快速响应）
     * - 最大线程数：10（高峰期扩展）
     * - 队列容量：1000（缓冲待处理任务）
     * - 拒绝策略：CallerRunsPolicy（由调用线程处理，避免丢失数据）
     * - 线程存活时间：60秒（空闲后回收）
     */
    @Bean(name = "logWriteBackExecutor")
    public Executor logWriteBackExecutor() {
        log.info("初始化日志回写线程池...");
        
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        
        // 核心线程数
        executor.setCorePoolSize(4);
        
        // 最大线程数
        executor.setMaxPoolSize(10);
        
        // 队列容量
        executor.setQueueCapacity(1000);
        
        // 线程名称前缀
        executor.setThreadNamePrefix("log-writeback-");
        
        // 线程存活时间（秒）
        executor.setKeepAliveSeconds(60);
        
        // 允许核心线程超时
        executor.setAllowCoreThreadTimeOut(false);
        
        // 等待任务完成后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        
        // 等待时间（秒）
        executor.setAwaitTerminationSeconds(60);
        
        // 拒绝策略：由调用线程处理
        // 这样可以避免日志丢失，虽然可能会阻塞调用线程
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        
        // 初始化
        executor.initialize();
        
        log.info("日志回写线程池初始化完成: corePoolSize={}, maxPoolSize={}, queueCapacity={}", 
            executor.getCorePoolSize(), 
            executor.getMaxPoolSize(), 
            executor.getQueueCapacity());
        
        return executor;
    }
    
    /**
     * 通用异步任务线程池
     * 
     * 用于其他异步操作（如邮件发送、告警通知等）
     */
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        log.info("初始化通用异步线程池...");
        
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        
        // 核心线程数
        executor.setCorePoolSize(2);
        
        // 最大线程数
        executor.setMaxPoolSize(5);
        
        // 队列容量
        executor.setQueueCapacity(500);
        
        // 线程名称前缀
        executor.setThreadNamePrefix("async-task-");
        
        // 线程存活时间（秒）
        executor.setKeepAliveSeconds(30);
        
        // 拒绝策略：丢弃最旧的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        
        // 初始化
        executor.initialize();
        
        log.info("通用异步线程池初始化完成");
        
        return executor;
    }
}

